﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DatabaseEntegreItri
{

    public class TimeEstimation
    {
        private const int SECOND_IN_MINUTE = 60;

        private int oldOperation = 0;
        private int MAX_SAMPLE_SIZE = 50;
        private int maxDataCount = 1;
        Queue<UpdateElement> queueList = new Queue<UpdateElement>();
        Queue<UpdateElement> queueListAll = new Queue<UpdateElement>();

        public TimeEstimation(int maxDataCount)
        {
            this.maxDataCount = maxDataCount;
        }
        /// <summary>
        /// Add Sample and get estimated time
        /// </summary>
        /// <param name="currentData"></param>
        /// <returns></returns>
        public double addNewSample(double currentGap, int currentOperation)
        {            
            UpdateElement newElement = new UpdateElement(currentOperation - oldOperation, currentGap);
            queueListAll.Enqueue(newElement);
            if (queueList.Count >= MAX_SAMPLE_SIZE)
            {
                queueList.Dequeue();
                queueList.Enqueue(newElement);
            }
            else
            {
                queueList.Enqueue(newElement);
            }
            double timeToFinish = queueList.Average(p => p.getAverage());

            double allAverage = queueListAll.Average(p=>p.getAverage());

            // mix with whole average
            timeToFinish = timeToFinish / 2 + allAverage/2;
            
            timeToFinish *= (maxDataCount - currentOperation); // multiply with remaining operation
            timeToFinish = milisToMinute(timeToFinish);

            oldOperation = currentOperation;
            
            // Few Sample
            // if (queueList.Count < 3 && currentPatient<10) { return -1; }
            
            return timeToFinish;
        }

        private double milisToMinute(double milis) {
            milis=((milis / 1000) / SECOND_IN_MINUTE);//converting milisecond to minute
            return Math.Round(milis, 1);
        }

        public void reset()
        {
            queueListAll.Clear();
            queueList.Clear();
        }

        private class UpdateElement
        {

            public int dataCount = 0;
            public double timeGap = 0;
            public UpdateElement(int dataCount, double timeGap)
            {
                this.dataCount = dataCount;
                this.timeGap = timeGap;
            }
            public double getAverage()
            {
                return timeGap / dataCount;
            }
        }
    }

}
